package db

import (
	"errors"
	"strconv"
)

type Table struct {
	//数据库
	DbName string
	//表名
	TableName string
	//表注释
	TableComment string
	//字段
	Fields []Field
}

// toString
func (t Table) String() string {
	return "DbName:" + t.DbName + ",TableName:" + t.TableName + ",TableComment:" + t.TableComment
}

type Field struct {
	//数据库
	DbName string
	//表名
	TableName        string
	Column           string //字段名
	LowerCamelColumn string //小驼峰名称
	UpperCamelColumn string //大驼峰名称
	Desc             string //描述
	Type             string //类型
	TypeLength       string //类型长度 , 如果是小数类型,  类型长度会出现小数点, 例如 decimal(10,2)  10,2

	//是否是自增
	IsAutoIncrement bool

	//是否是非空
	IsNotNull bool
	//是默认值
	DefaultValue string

	//是否是主键索引
	IsPrimaryKey bool

	//是否是唯一 索引
	IsUnique bool

	//普通索引
	IsIndex bool

	// 字段位置
	Position int

	//自定义
	Custom string
}

func (t Field) String() string {
	return "DbName:" + t.DbName + ",TableName:" + t.TableName + ",Column:" + t.Column + ",Desc:" + t.Desc + ",Type:" +
		t.Type + ",TypeLength:" + t.TypeLength + ",IsAutoIncrement:" + strconv.FormatBool(t.IsAutoIncrement) +
		",IsNotNull:" + strconv.FormatBool(t.IsNotNull) + ",DefaultValue:" + t.DefaultValue + ",IsPrimaryKey:" +
		strconv.FormatBool(t.IsPrimaryKey) + ",IsUnique:" + strconv.FormatBool(t.IsUnique) + ",IsIndex:" +
		strconv.FormatBool(t.IsIndex) + ",Position:" + strconv.Itoa(t.Position)

}

type TableInfo interface {
	//获取表信息
	GetTableInfo(c ConnectLogo, tableName string) (*Table, error)
}

// 根据类型自动获取表信息
func GetTableInfo(c ConnectLogo, tableName string) (*Table, error) {
	var tableInfo TableInfo
	switch c.Type {
	case MYSQL:
		tableInfo = &TableInfoMysql{}
	case ORACLE:
		tableInfo = &TableInfoOracle{}
	default:
		return nil, errors.New("未知数据库类型")
	}
	return tableInfo.GetTableInfo(c, tableName)
}

type TableInfoMysql struct {
}

func (t *TableInfoMysql) GetTableInfo(c ConnectLogo, tableName string) (*Table, error) {
	var table Table

	db := GetDb(c)
	defer db.Close()
	//查询表信息
	rows, err := db.Query(`select TABLE_SCHEMA, TABLE_NAME, TABLE_COMMENT
										from information_schema.tables
										where table_name = ?
										  and table_schema = ?`, tableName, c.DbName)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	for rows.Next() {
		err = rows.Scan(&table.DbName, &table.TableName, &table.TableComment)
		if err != nil {
			panic(err)
		}
	}
	//查询字段信息
	rows, err = db.Query(`
select
       TABLE_SCHEMA,   #数据库名
       TABLE_NAME,     #表名
       COLUMN_NAME,    #字段名
       DATA_TYPE,      #字段类型
       COLUMN_DEFAULT, #默认值
       #数据类型长度 ,截取括号内的数字
       trim( SUBSTRING(COLUMN_TYPE, LOCATE('(', COLUMN_TYPE) + 1,
                 LOCATE(')', COLUMN_TYPE) - LOCATE('(', COLUMN_TYPE) - 1))
       as COLUMN_LENGTH,
       
       # 索引
       COLUMN_KEY,     #PRI 主键 UNI 唯一索引  MUL 普通索引
       #自增
       EXTRA,          #auto_increment 自增
       
        #是否为空
        IS_NULLABLE,     #YES 可以为空 NO 不可以为空

        COLUMN_COMMENT,  #字段注释
		ORDINAL_POSITION #字段位置
from information_schema.columns
where table_name = ?
  and table_schema = ?
`, tableName, c.DbName)

	if err != nil {
		panic(err)
	}
	defer rows.Close()

	toMaps := RowsToMap(rows)
	for _, maps := range toMaps {
		var field Field
		for col, value := range maps {
			//如果第1列是数据库名
			if col == "TABLE_SCHEMA" {
				field.DbName = value
				continue
			}

			//如果第2列是表名
			if col == "TABLE_NAME" {
				field.TableName = value
				continue
			}

			//如果第3列是字段名
			if col == "COLUMN_NAME" {
				field.Column = value
				continue
			}

			//如果第4列是字段类型
			if col == "DATA_TYPE" {
				field.Type = value
				continue
			}

			//如果第5列是默认值
			if col == "COLUMN_DEFAULT" {
				field.DefaultValue = value
				continue
			}

			//如果第6列是数据类型长度
			if col == "COLUMN_LENGTH" {
				field.TypeLength = value
				continue
			}

			//如果第7列是PRI 则是主键,第7列是MUL 则是普通索引,第7列是UNI 则是唯一索引
			if col == "COLUMN_KEY" {
				if value == "PRI" {
					field.IsPrimaryKey = true
				} else if value == "MUL" {
					field.IsIndex = true
				} else if value == "UNI" {
					field.IsUnique = true
				} else {
					panic("未知索引类型:" + value)
				}
				continue
			}
			//如果第8列是auto_increment 则是自增
			if col == "EXTRA" {
				if value == "auto_increment" {
					field.IsAutoIncrement = true
				}
				continue
			}
			//如果第9列是YES 则是可以为空,NO 则是不可以为空
			if col == "IS_NULLABLE" {
				if value == "NO" {
					field.IsNotNull = true
				}
				continue
			}
			//如果第10列是字段注释
			if col == "COLUMN_COMMENT" {
				field.Desc = value
				continue
			}

			// 字段位置
			if col == "ORDINAL_POSITION" {
				atoi, err := strconv.Atoi(value)
				if err != nil {
					panic(err)
				}
				field.Position = atoi
				continue
			}

		}
		table.Fields = append(table.Fields, field)
	}

	return &table, nil
}

type TableInfoOracle struct {
}

func (t *TableInfoOracle) GetTableInfo(c ConnectLogo, tableName string) (*Table, error) {
	//var table Table
	return nil, nil
}
